//-----------------------------------------------------------------------
// <copyright file="AddAcl.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Andy Reeves</author>
// <email>andyr</email>
// <date>2004-03-23</date>
// <summary>Adds an Access Control List Entry to a file or folder.</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.Security
{
    using System.Globalization;
    using System;
    using System.Xml;
    using Microsoft.Build.Framework;
    using System.IO;
    using Microsoft.Sdc.Tasks.Configuration.Win32Security;
    /// <summary>
    /// Adds an Access Control List Entry to a file or folder.
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[<Security.AddAcl Path="path" ApplyTo="applyTo" UserOrGroup="userOrGroup" AccessType="accessType" />]]></code>
    /// <para>where:</para>
    /// <para><i>path (Required)</i></para>
    /// <para>The path to the file or folder.</para>
    /// <para><i>applyTo</i></para>
    /// <para>Either ThisFolder, SubFolders or Files.</para>
    /// <para><i>userOrGroup (Required)</i></para>
    /// <para>A domain user or group i.e. mydomain\user1.</para>
    /// <para><i>accessType (Required)</i></para>
    /// <para>The permissions required i.e. Read Write.</para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <Security.AddAcl
    ///             Path="c:\temp"
    ///             ApplyTo="ThisFolder SubFolders Files"
    ///             UserOrGroup="mydomain\user1"
    ///             AccessType="Read Write" />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public class AddAcl : TaskBase
    {
        private string path;
        private string applyTo = String.Empty;
        private string userOrGroup;
        private string accessTypeString;

        /// <summary>
        /// Initializes a new instance of the AddAcl class.
        /// </summary>
        public AddAcl()
        {
        }

        /// <summary>Specifies the path to the file or folder that this ACL will be applied to.</summary>
        /// <value>The full path to the file or folder.</value>
        [Required]
        public string Path
        {
            get
            {
                return (this.path == null ? String.Empty : this.path);
            }
            set
            {
                this.path = value;
            }
        }
        /// <summary>Specifies how this ACE is applied i.e. ThisFolder</summary>
        /// <remarks>
        /// <para>What to apply this ACL to i.e. ThisFolder, SubFolders, or Files. Separate multiple values with a space.</para>
        /// <para>Defaults to all.</para>
        /// <para>Possible values are:</para>
        /// <para>ThisFolder</para>
        /// <para>SubFolder</para>
        /// <para>Files</para>
        /// </remarks>
        /// <value>This is how the ACE is applied</value>
        public string ApplyTo
        {
            get
            {
                return (this.applyTo == null ? String.Empty : this.applyTo);
            }
            set
            {
                this.applyTo = value;
            }
        }

        /// <summary>Specifies the user or group that this ACL will be applied for.</summary>
        /// <example>domain\user1</example>
        /// <value>The name of the user or group.</value>
        [Required]
        public string UserOrGroup
        {
            get
            {
                return (this.userOrGroup == null ? String.Empty : this.userOrGroup);
            }
            set
            {
                this.userOrGroup = value;
            }
        }

        /// <summary>
        /// Specifies the type of Access to grant.
        /// </summary>
        /// <remarks>
        /// <para>The type of access i.e. Read or Delete etc. Separate multiple values with a space.</para>
        /// <para>Possible values are:</para>
        /// <para>FullControl</para>
        /// <para>TraverseFolderExecuteFile</para>
        /// <para>ListFolderReadData</para>
        /// <para>ReadAttributes</para>
        /// <para>ReadExtendedAttributes</para>
        /// <para>CreateFilesWriteData</para>
        /// <para>CreateFoldersAppendData</para>
        /// <para>WriteAttributes</para>
        /// <para>WriteExtendedAttributes</para>
        /// <para>DeleteSubfoldersAndFiles</para>
        /// <para>Delete</para>
        /// <para>ReadPermissions</para>
        /// <para>ChangePermissions</para>
        /// <para>TakeOwnership</para>
        /// <para>Modify</para>
        /// <para>ReadAndExecute</para>
        /// <para>ListFolderContents</para>
        /// <para>Read</para>
        /// <para>Write</para>
        /// </remarks>
        /// <value>The type of access.</value>
        [Required]
        public string AccessType
        {
            get
            {
                return (this.accessTypeString == null ? String.Empty : this.accessTypeString);
            }
            set
            {
                this.accessTypeString = value;
            }
        }

        /// <summary>
        /// Performs the action of this task.
        /// </summary>
        protected override void InternalExecute()
        {
            Log.LogMessageFromResources("Acl.AddPermissions", this.userOrGroup, this.path);

            AceFlags aceFlags = 0;

            if (this.applyTo.Length == 0)
            {
                aceFlags = AceFlags.All;
            }
            else
            {
                string[] applyToSplit = this.applyTo.Split(' ');
                foreach (string applyToSplitItem in applyToSplit)
                {
                    object flags = Enum.Parse(typeof(AceFlags), applyToSplitItem, true);
                    aceFlags = aceFlags | (AceFlags)flags;
                }
            }

            AccessTypes accessType = 0;
            string[] accessTypeStringSplit = this.accessTypeString.Split(' ');
            foreach (string accessTypeStringSplitItem in accessTypeStringSplit)
            {
                object type = Enum.Parse(typeof(AccessTypes), accessTypeStringSplitItem, true);
                accessType = accessType | (AccessTypes)type;
            }

            Microsoft.Sdc.Tasks.Configuration.Win32Security.Acl.AddAce(this.userOrGroup, this.path, aceFlags, accessType);
        }
    }
}

